package com.martin.lib_base.model

import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.martin.lib_base.R
import com.martin.lib_base.base.BaseViewHolder
import com.martin.lib_base.bean.FileBean
import com.martin.lib_base.common.CommonAdapter
import com.martin.lib_base.databinding.ItemMultipleImagePickBinding
import com.martin.lib_base.interfaces.IItemData
import com.martin.lib_base.interfaces.ILoading
import com.martin.lib_base.interfaces.IOnItemClickListener
import com.martin.lib_base.ktx.getScope
import com.martin.lib_base.ktx.loge
import com.martin.lib_base.ktx.showToast
import com.martin.lib_base.ktx.toJson
import com.martin.lib_base.utils.MediaUtil
import com.martin.lib_base.utils.UploadUtil
import dev.DevUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlin.properties.Delegates

class MultipleImagePickModel(
    // 最大选择数量
    private val maxCount: Int = 9,
    // 是否需要上传
    private val needUpload: Boolean = false,
    // 选择提示
    private val tip: String = "选择图片",
    /**
     * 回调
     * 选择完图片后都会调起
     */
    private val callBack: () -> Unit = {}
) {

    // 适配器
    private var adapter: CommonAdapter by Delegates.notNull()

    /**
     * 绑定RecyclerView
     */
    fun bindRecyclerView(rv: RecyclerView) {
        adapter = CommonAdapter(rv.context, listOf(MultipleImagePickViewHolder::class.java))
        rv.adapter = adapter
        // 刷新列表
        adapter.refresh(listOf(
            FileBean().apply {
                url = tip
            }
        ))

        adapter.addOnItemClickListener(object : IOnItemClickListener {
            override fun onItemClick(position: Int, type: Int) {
                val fileBean = adapter.getItem(position) as FileBean
                when (type) {
                    0 -> {
                        if (fileBean.path.isNullOrEmpty()) {
                            pickImage()
                        }
                    }

                    R.id.iv_remove -> {
                        adapter.removeItem(position)
                        // 如果数量不是最大,并且没有添加按钮,则增加添加按钮
                        val find = adapter.items.find { item ->
                            (item as FileBean).path.isNullOrEmpty()
                        }
                        if (getFileList().size < maxCount && find == null) {
                            adapter.addItem(FileBean().apply {
                                url = tip
                            })
                        }
                    }

                    else -> {
                        showToast("未知点击事件")
                    }
                }
            }
        })
    }


    /**
     * 选择图片
     */
    private fun pickImage() {
        MediaUtil.pickImage(DevUtils.getTopActivity(), maxCount - getFileList().size) { list ->
            flow {
                list.forEach {
                    emit(it)
                }
            }
                // 上传图片
                .map {
                    val fileBean = FileBean()
                    fileBean.path = it.realPath
                    if (needUpload) {
                        fileBean.url = UploadUtil.upload(it.realPath).data?.file
                    }
                    fileBean
                }
                // 切换上传线程
                .flowOn(Dispatchers.IO)
                // 上传成功
                .onEach {
                    loge("收集FileBean : ${it.toJson(false)}")
                    // 如果数量已达到临近最大,则删除添加按钮
                    if (getFileList().size >= maxCount - 1) {
                        adapter.items.find { item -> (item as FileBean).path.isNullOrEmpty() }
                            ?.let { item ->
                                adapter.removeItem(adapter.items.indexOf(item))
                            }
                        adapter.addItem(it)
                    } else {
                        adapter.addItem(it, adapter.itemCount - 1)
                    }
                }
                // 切换上传成功后的线程
                .flowOn(Dispatchers.Main)
                // 异常处理
                .catch {
                    loge("上传图片异常 : ${it.toJson()}")
                    showToast("图片上传失败")
                }
                // 开始上传,展示loading
                .onStart {
                    (adapter.context as? ILoading)?.showLoading()
                    adapter
                }
                // 上传完成,隐藏loading
                .onCompletion {
                    (adapter.context as? ILoading)?.dismissLoading()
                    callBack()
                }
                .launchIn(DevUtils.getTopActivity().getScope())
        }
    }

    /**
     * 获取选择的图片列表
     */
    fun getFileList(): List<FileBean> {
        return adapter.items.map { it as FileBean }.filter {
            !it.path.isNullOrEmpty()
        }
    }

    companion object {
        @com.martin.lib_base.annotation.ItemData(ItemData::class)
        class MultipleImagePickViewHolder(view: View) :
            BaseViewHolder<FileBean, ItemMultipleImagePickBinding>(view) {

            override fun onBindViewHolder(position: Int, item: Any?) {
                binding.bean = getItemBean(item)

                // 条目点击
                itemView.setOnClickListener {
                    notifyItemClick()
                }

                // 移除图片点击
                binding.ivRemove.setOnClickListener {
                    notifyItemClick(R.id.iv_remove)
                }
            }
        }

        class ItemData : IItemData {
            override fun getItemLayoutId() = R.layout.item_multiple_image_pick
        }
    }
}